#########################################################################################################################
##### Replication Code for "Do Institutions Matter? The Impact of Budget Expertise on State Fiscal Responsibility" ######
############################ Accepted at Journal of Public Administration Research and Theory ###########################
#########################################################################################################################

# Colin Emrich - 09/11/2022
# Please contact me at colinemrich51@gmail.com if there are any questions.

######################################################################
#################### Installing required packages ####################
######################################################################

# install.packages("haven")
# install.packages("usmap")
# install.packages("ggplot2")
# install.packages("tidyverse")
# install.packages("panelView")
# install.packages("lfe")
# install.packages("broom")
# install.packages("dotwhisker")
# install.packages("plyr")
# install.packages("gridExtra")
# install.packages("ggfortify")
# install.packages("Hmisc")
# install.packages("lme4")
# install.packages("arm")
# install.packages("stargazer")
# install.packages("ggeffects")
# install.packages("knitr")
# install.packages("PanelMatch")
# install.packages("gsynth")

library(haven)
library(usmap)
library(ggplot2)
library(tidyverse)
library(panelView)
library(lfe)
library(broom)
library(dotwhisker)
library(plyr)
library(gridExtra)
library(ggfortify)
library(Hmisc)
library(lme4)
library("arm")
library(stargazer)
library(ggeffects)
library(knitr)
library(PanelMatch)
library(gsynth)

######################################################################
##################### Setting working directory ######################
######################################################################

### Set up
rm(list=ls()) #remove everything in the environment
### Set working directory (to your current project data folder)
setwd("Downloads")


######################
###### Figure 1 ######
######################

Nonpartisan_Fiscal <- read_dta("Nonpartisan_Fiscal_Office_Information_OnePerState.dta")
Nonpartisan_Fiscal_1 <- as.data.frame(Nonpartisan_Fiscal)
Nonpartisan_Fiscal_1$state <- Nonpartisan_Fiscal_1$State
Nonpartisan_Fiscal_2 <- select(Nonpartisan_Fiscal_1, Nonpartisan, state)

plot_usmap(data = Nonpartisan_Fiscal_2, values = "Nonpartisan") +
  ggtitle("Figure 1: States with Nonpartisan Fiscal Offices") +
  theme(plot.title = element_text(size=12, face = "bold")) +
  scale_fill_brewer(breaks = c("Yes", "No"), type = "qual", palette="Greys", name = "Nonpartisan") +
  theme(legend.justification=c(1,0), legend.position=c(0.995,0.005), legend.title = element_text(size=8)) +
  theme(panel.background = element_rect(colour = "black", fill = "white")) 

######################
###### Figure 2 ######
######################

load("C:/Users/Colin/Desktop/Dissertation/Dissertation Data/Paper 3/Paper_3_Data.RData")

Paper_3_Data_2014 <- subset(Paper_3_Data, year < 2014.5)

panelview(state ~ nonpartisan_fiscal, data = Paper_3_Data_2014, index = c("state", "year"), axis.lab.gap = c(5, 0),
          by.timing = TRUE, main = "Figure 2: States and Nonpartisan Fiscal Offices \nfrom 1942-2014 - Treatment Status", xlab = "Year", ylab = "State", background = "white", cex.main = 12, cex.legend = 10, cex.axis = 5, cex.lab = 10)


######################
###### Figure 3 ######
######################

ggplot(Paper_3_Data, aes(x=year, y = gensurplus_percentgsp)) + 
  geom_smooth(method = lm, se = FALSE, aes(color=factor(nonpartisan_fiscal))) + theme_bw() +
  ylab("Percent General Surplus") + xlab("Year") + ggtitle("Figure 3: State General Budget Surplus by Type of Fiscal Office") + 
  theme(legend.position="bottom") + scale_color_discrete(name = "Type of Fiscal Office", labels = c("Partisan", "Nonpartisan")) +
  theme(plot.title = element_text(size=11, face = "bold"))

######################
###### Figures 5.1 and 5.2 ######
######################

Paper_3_Data <- as.data.frame(Paper_3_Data)

Paper_3_Data$year <- type.convert(Paper_3_Data$year)

Paper_3_Data$nonpartisan_fiscal <- type.convert(Paper_3_Data$nonpartisan_fiscal)

PM.results_general_forecast <- PanelMatch(lag = 3, time.id = "year", unit.id = "state_numeric",
                                          treatment = "nonpartisan_fiscal", refinement.method = "mahalanobis", 
                                          data = Paper_3_Data, match.missing = T,
                                          covs.formula = ~ lag_gensurplus_percentgsp + chgreal1incpc + unemploy_a + governor_budget_control_index + legprof_squire + 
                                            debt_percentgsp + gub_party_change + ranney4_control + govparty_c + budgets_overseen + Supermajority_Budget + budget_forecast_numeric +
                                            policysociallib_est + policyeconlib_est + masssociallib_est + masseconlib_est,
                                          size.match = 5, qoi = "att", outcome.var = "gensurplus_percentgsp", 
                                          lead = 0:5, forbid.treatment.reversal = FALSE)

PE.results_general_forecast <- PanelEstimate(sets = PM.results_general_forecast, data = Paper_3_Data)

plot(PE.results_general_forecast, 
     main = "Figure 4: Effect of Nonpartisan Fiscal Offices \non General Budget Surplus",
     ylab = "Estimated Effect of Nonpartisan Fiscal Offices", cex.main = 1, cex.lab = 0.75)


Paper_3_Data_forecast_leg <- subset(Paper_3_Data, budget_forecast_numeric == 1)

Paper_3_Data_forecast_exec <- subset(Paper_3_Data, budget_forecast_numeric == 0)

## When leg controls budget forecast

PM.results_general_forecast_leg <- PanelMatch(lag = 3, time.id = "year", unit.id = "state_numeric",
                                              treatment = "nonpartisan_fiscal", refinement.method = "mahalanobis", 
                                              data = Paper_3_Data_forecast_leg, match.missing = T,
                                              covs.formula = ~ lag_gensurplus_percentgsp + chgreal1incpc + unemploy_a + governor_budget_control_index + legprof_squire + 
                                                debt_percentgsp + gub_party_change + ranney4_control + govparty_c + budgets_overseen + Supermajority_Budget +
                                                policysociallib_est + policyeconlib_est + masssociallib_est + masseconlib_est,
                                              size.match = 5, qoi = "att", outcome.var = "gensurplus_percentgsp", 
                                              lead = 0:5, forbid.treatment.reversal = FALSE)

PE.results_general_forecast_leg <- PanelEstimate(sets = PM.results_general_forecast_leg, data = Paper_3_Data_forecast_leg)

## When exec (or combined group) controls budget forecast

PM.results_general_forecast_exec <- PanelMatch(lag = 3, time.id = "year", unit.id = "state_numeric",
                                               treatment = "nonpartisan_fiscal", refinement.method = "mahalanobis", 
                                               data = Paper_3_Data_forecast_exec, match.missing = T,
                                               covs.formula = ~ lag_gensurplus_percentgsp + chgreal1incpc + unemploy_a + governor_budget_control_index + legprof_squire + 
                                                 debt_percentgsp + gub_party_change + ranney4_control + govparty_c + budgets_overseen + Supermajority_Budget +
                                                 policysociallib_est + policyeconlib_est + masssociallib_est + masseconlib_est,
                                               size.match = 5, qoi = "att", outcome.var = "gensurplus_percentgsp", 
                                               lead = 0:5, forbid.treatment.reversal = FALSE)

PE.results_general_forecast_exec <- PanelEstimate(sets = PM.results_general_forecast_exec, data = Paper_3_Data_forecast_exec)

par(mfrow=c(1,2))

plot(PE.results_general_forecast_leg, 
     main = "Figure 5.1: Effect of Nonpartisan Fiscal Offices \non General Budget Surplus \n(Legislature Controls Revenue Forecast)",
     ylab = "Estimated Effect of Nonpartisan Fiscal Offices", cex.main = 0.75, cex.lab = 0.75)


plot(PE.results_general_forecast_exec, 
     main = "Figure 5.2: Effect of Nonpartisan Fiscal Offices \non General Budget Surplus \n(Executive Controls Revenue Forecast)",
     ylab = "Estimated Effect of Nonpartisan Fiscal Offices", cex.main = 0.75, cex.lab = 0.75)


######################
###### Table 1 (Appendix 1.1) ######
######################

Nonpartisan_Fiscal_Table <- read_dta("Nonpartisan_Fiscal_Office_Information_OnePerState.dta")
kable(Nonpartisan_Fiscal_Table, caption = "State Budget Expertise List", caption.placement = 'top', align = "c")


######################
###### Figure 6 (Appendix 1.2) ######
######################

Paper_3_Data <- as.data.frame(Paper_3_Data)

Paper_3_Data_2014 <- subset(Paper_3_Data, year < 2014.5)

panelview(state ~ nonpartisan_fiscal, data = Paper_3_Data_2014, index = c("state", "year"), axis.lab.gap = c(5, 0),
          main = "Figure 6: States and Nonpartisan Fiscal Offices \nfrom 1942-2014 - Treatment Status", xlab = "Year", ylab = "State", background = "white", cex.main = 12, cex.legend = 10, cex.axis = 5, cex.lab = 10)


######################
###### Figure 7 (Appendix 1.4) ######
######################

Nonpartisan_Fiscal_ATT <- read_dta("Nonpartisan_Fiscal_Office_Information_OnePerState_ATT_21states.dta")
Nonpartisan_Fiscal_ATT_1 <- as.data.frame(Nonpartisan_Fiscal_ATT)
Nonpartisan_Fiscal_ATT_1$state <- Nonpartisan_Fiscal_ATT_1$State
Nonpartisan_Fiscal_ATT_2 <- select(Nonpartisan_Fiscal_ATT_1, state, ATTNonpartisan)

plot_usmap(data = Nonpartisan_Fiscal_ATT_2, values = "ATTNonpartisan") +
  ggtitle("Figure 7: Map of ATT Estimates by State") +
  theme(plot.title = element_text(size=13, face = "bold")) +
  scale_fill_brewer(breaks = c("Yes", "No (Nonpartisan)", "No (Partisan)"), type = "qual", palette="Greys", name = "ATT Estimated") +
  theme(legend.justification=c(1,0), legend.position=c(0.995,0.005), legend.title = element_text(size=8)) +
  theme(panel.background = element_rect(colour = "black", fill = "white")) 


######################
###### Figure 8 (Appendix 2.1) ######
######################

PM.results_total_forecast <- PanelMatch(lag = 3, time.id = "year", unit.id = "state_numeric",
                                        treatment = "nonpartisan_fiscal", refinement.method = "mahalanobis", 
                                        data = Paper_3_Data, match.missing = T,
                                        covs.formula = ~ lag_totalsurplus_percentgsp + chgreal1incpc + unemploy_a + governor_budget_control_index + legprof_squire +
                                          debt_percentgsp + gub_party_change + ranney4_control + govparty_c + budgets_overseen + Supermajority_Budget + budget_forecast_numeric +
                                          policysociallib_est + policyeconlib_est + masssociallib_est + masseconlib_est,
                                        size.match = 5, qoi = "att", outcome.var = "totalsurplus_percentgsp", 
                                        lead = 0:5, forbid.treatment.reversal = FALSE)

PE.results_total_forecast <- PanelEstimate(sets = PM.results_total_forecast, data = Paper_3_Data)

plot(PE.results_total_forecast, 
     main = "Figure 8: Effect of Nonpartisan Fiscal Offices \non Total Budget Surplus",
     ylab = "Estimated Effect of Nonpartisan Fiscal Offices", cex.main = 0.75, cex.lab = 0.75)



######################
###### Table 6 (Appendix 2.4.1) ######
######################

library(fixest)

jawn_H1_1 <- feols(gensurplus_percentgsp ~ nonpartisan_fiscal | state + year, Paper_3_Data)

jawn_H1_2 <- feols(gensurplus_percentgsp ~ nonpartisan_fiscal + lag_gensurplus_percentgsp | state + year, Paper_3_Data)

jawn_H1_3 <- feols(gensurplus_percentgsp ~ nonpartisan_fiscal + chgreal1incpc + unemploy_a + governor_budget_control_index + legprof_squire + 
                     debt_percentgsp + gub_party_change + ranney4_control + govparty_c + budgets_overseen + Supermajority_Budget + budget_forecast_numeric +
                     policysociallib_est + policyeconlib_est + masssociallib_est + masseconlib_est | state + year, Paper_3_Data)

jawn_H1_4 <- feols(gensurplus_percentgsp ~ nonpartisan_fiscal + lag_gensurplus_percentgsp + chgreal1incpc + unemploy_a + governor_budget_control_index + legprof_squire + 
                     debt_percentgsp + gub_party_change + ranney4_control + govparty_c + budgets_overseen + Supermajority_Budget + budget_forecast_numeric +
                     policysociallib_est + policyeconlib_est + masssociallib_est + masseconlib_est | state + year, Paper_3_Data)


######################
###### Figures 9 and 10 (Appendix 2.4.2) ######
######################

out <- gsynth(gensurplus_percentgsp ~ nonpartisan_fiscal + lag_gensurplus_percentgsp + chgreal1incpc + unemploy_a + govparty_c + budget_forecast_numeric +
                policysociallib_est + policyeconlib_est + masssociallib_est + masseconlib_est, data = Paper_3_Data, index = c("state", "year"), 
              force = "two-way", CV = TRUE,
              se = TRUE, inference = "parametric", nboots = 1000, parallel = FALSE, na.rm = TRUE)


plot1 <- plot(out, type = "gap", xlim = c(-5, 10), main = "Figure 9: Estimated ATT")

plot2 <- plot(out, type = "counterfactual", raw= "band", xlim = c(-5, 10), main = "Figure 10: Estimated ATT (with Counterfactual)", ylab = "Coefficient")


######################
###### Figures 11 and 12 (Appendix 2.5) ######
######################


Paper_3_Data <- as.data.frame(Paper_3_Data)

Paper_3_Data$year <- type.convert(Paper_3_Data$year)

Paper_3_Data$nonpartisan_fiscal <- type.convert(Paper_3_Data$nonpartisan_fiscal)

## General Surpluses Per Capita

PM.results_general_forecast_capita <- PanelMatch(lag = 3, time.id = "year", unit.id = "state_numeric",
                                                 treatment = "nonpartisan_fiscal", refinement.method = "mahalanobis", 
                                                 data = Paper_3_Data, match.missing = T,
                                                 covs.formula = ~ lag_gensurplus_capita + chgreal1incpc + unemploy_a + governor_budget_control_index + legprof_squire + 
                                                   debt_percentgsp + gub_party_change + ranney4_control + govparty_c + budgets_overseen + Supermajority_Budget + budget_forecast_numeric +
                                                   policysociallib_est + policyeconlib_est + masssociallib_est + masseconlib_est,
                                                 size.match = 5, qoi = "att", outcome.var = "gensurplus_capita", 
                                                 lead = 0:5, forbid.treatment.reversal = FALSE)

PE.results_general_forecast_capita <- PanelEstimate(sets = PM.results_general_forecast_capita, data = Paper_3_Data)

plot(PE.results_general_forecast_capita, 
     main = "Figure 11: Effect of Nonpartisan Fiscal Offices \non General Budget Surplus Per Capita",
     ylab = "Estimated Effect of Nonpartisan Fiscal Offices", cex.main = 1, cex.lab = 0.75)


## General Surpluses as a % of State Budget

PM.results_general_forecast_exp_budget <- PanelMatch(lag = 3, time.id = "year", unit.id = "state_numeric",
                                                     treatment = "nonpartisan_fiscal", refinement.method = "mahalanobis", 
                                                     data = Paper_3_Data, match.missing = T,
                                                     covs.formula = ~ lag_gensurplus_exp_budget + chgreal1incpc + unemploy_a + governor_budget_control_index + legprof_squire + 
                                                       debt_percentgsp + gub_party_change + ranney4_control + govparty_c + budgets_overseen + Supermajority_Budget + budget_forecast_numeric +
                                                       policysociallib_est + policyeconlib_est + masssociallib_est + masseconlib_est,
                                                     size.match = 5, qoi = "att", outcome.var = "gensurplus_exp_budget", 
                                                     lead = 0:5, forbid.treatment.reversal = FALSE)

PE.results_general_forecast_exp_budget <- PanelEstimate(sets = PM.results_general_forecast_exp_budget, data = Paper_3_Data)


plot(PE.results_general_forecast_exp_budget, 
     main = "Figure 12: Effect of Nonpartisan Fiscal Offices \non General Budget Surplus (% State Budget Expenditures)",
     ylab = "Estimated Effect of Nonpartisan Fiscal Offices", cex.main = 1, cex.lab = 0.75)


######################
###### Table 8 (Appendix 3.1) ######
######################

Nonpartisan_Forecast_Table <- read_dta("Nonpartisan_Fiscal_Forecast_Responsibility.dta")
kable(Nonpartisan_Forecast_Table, col.names = c("State", "Responsibility", "Fiscal Years"),
      caption = "Institutional Actor Responsibility for Official Revenue Forecasts", caption.placement = 'top', align = "c")
